package com.zmc.product.infrastructure.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmc.common.domain.resp.order.OrderReduceInventoryResp;
import com.zmc.common.domain.resp.product.ProductInventoryResp;
import com.zmc.common.domain.vo.good.GoodsInventoryVo;
import com.zmc.common.domain.vo.good.GoodsUpVo;
import com.zmc.common.domain.vo.inventory.InventoryInitVo;
import com.zmc.common.exception.base.BusinessException;
import com.zmc.product.infrastructure.dao.InventoryGoodsStockDao;
import com.zmc.product.infrastructure.entity.InventoryGoodsStockEntity;
import com.zmc.product.infrastructure.enums.InventoryStatusEnum;
import com.zmc.product.infrastructure.service.InventoryGoodsStockService;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;


/**
 * @author zmc
 */
@Service("inventoryGoodsStockService")
public class InventoryGoodsStockServiceImpl extends ServiceImpl<InventoryGoodsStockDao, InventoryGoodsStockEntity> implements InventoryGoodsStockService {

    public static final Logger log = LoggerFactory.getLogger(InventoryGoodsStockServiceImpl.class);

    @Override
    @Transactional
    public void saveInventory(InventoryInitVo vo) {
        InventoryGoodsStockEntity stockEntity = new InventoryGoodsStockEntity();
        stockEntity.setSkuId(vo.getSkuId());
        stockEntity.setLockedStockQuantity(0L);
        stockEntity.setSaleStockQuantity(0L);
        stockEntity.setSaledStockQuantity(0L);
        stockEntity.setStockStatus(InventoryStatusEnum.INVENTORY_HAS_NO_STOCK.getCode());
        save(stockEntity);
    }

    @Override
    public List<ProductInventoryResp> check(GoodsInventoryVo vo) {
        LambdaQueryWrapper<InventoryGoodsStockEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(InventoryGoodsStockEntity::getSkuId, vo.getSkuIds());
        List<InventoryGoodsStockEntity> list = list(wrapper);
        return list.stream().filter(item -> item.getSaleStockQuantity() > 0).map(item -> {
            return new ProductInventoryResp(item.getSkuId(), item.getSaleStockQuantity());
        }).collect(Collectors.toList());
    }

    @Override
    public InventoryGoodsStockEntity getBySkuId(String skuId) {
        LambdaQueryWrapper<InventoryGoodsStockEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InventoryGoodsStockEntity::getSkuId, skuId);
        return getOne(wrapper);
    }

    @Override
    @Transactional
    public void deleteBySkuId(String skuId) {
        LambdaQueryWrapper<InventoryGoodsStockEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InventoryGoodsStockEntity::getSkuId, skuId);
        remove(wrapper);
    }

    @Override
    @Transactional
    public OrderReduceInventoryResp lockStock(List<GoodsUpVo> list) {
        OrderReduceInventoryResp resp = new OrderReduceInventoryResp();
        resp.setSuccess(true);
        for (GoodsUpVo vo : list) {
            boolean flag = baseMapper.lockStock(vo);
            if (!flag) {
                log.error("库存不足,锁定库存失败: list:{}", JSON.toJSONString(list));
                resp.setSuccess(false);
                resp.setSkuId(vo.getSkuId());
                break;
            }
        }
        return resp;
    }

    @Override
    public void upToInventory(List<GoodsUpVo> list) {
        baseMapper.batchUpToInventory(list);
    }


    @Override
    @Transactional
    public void unlockStock(List<GoodsUpVo> list) {
        baseMapper.batchUnlockStock(list);
    }

    @Override
    @Transactional
    public void reduceStock(List<GoodsUpVo> list) {
        baseMapper.batchReduceStock(list);
    }

    @Override
    public void returnStock(List<GoodsUpVo> list) {
        baseMapper.batchReturnStock(list);
    }

}